package com.example.study_backstage.config.shiro;

import com.example.study_backstage.constant.CommonConstant;
import com.example.study_backstage.entity.SysUser;
import com.example.study_backstage.entity.dto.LoginUser;
import com.example.study_backstage.filter.JwtToken;
import com.example.study_backstage.service.SysUserService;
import com.example.study_backstage.utils.JwtUtil;
import com.example.study_backstage.utils.RedisUtil;
import com.example.study_backstage.utils.TokenUtils;
import com.example.study_backstage.utils.oConvertUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @author lxw
 * @version 1.0
 * @data 2023/3/22
 */
public class UserRealm extends AuthorizingRealm  {

    @Resource
    private SysUserService sysUserService;
    @Resource
    private RedisUtil redisUtil;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了授权。。。");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        return info;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
        System.out.println("执行了认证。。。。。");
        String token = (String) auth.getCredentials();
        if (token == null) {
            throw new AuthenticationException("token为空!");
        }
        //校验token有效性
        SysUser sysUser = null;
        try {
            sysUser = this.checkUserToken(token);
        } catch (AuthenticationException e) {
            e.printStackTrace();
            return null;
        }
        return new SimpleAuthenticationInfo(sysUser, token, getName());
    }

    /**
     * 校验token有效性
     * @param token
     * @return
     */
    public SysUser checkUserToken(String token){
        // 解密获得username，用于和数据库进行对比
        String username = JwtUtil.getUsername(token);
        if (username == null) {
            throw new AuthenticationException("token非法无效!");
        }
        // 查询用户信息
        //SysUser user = sysUserService.getUser(username);
        SysUser loginUser = TokenUtils.getLoginUser(username, sysUserService, redisUtil);
        if (oConvertUtils.isEmpty(loginUser)){//判断是否为空
            throw new AuthenticationException("用户不存在!");
        }
        //判断用户token是否过期
        if (!TokenUtils.jwtTokenRefresh(token,redisUtil)){
            throw new AuthenticationException(CommonConstant.TOKEN_IS_INVALID_MSG);
        }
        return loginUser;
    }


    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }
}
